<template>
  <div class="content-area">
    <!-- 日历视图头部 -->
    <div class="calendar-header">
      <div class="calendar-controls">
        <el-button-group>
          <el-button
            @click="changeView('month')"
            :type="currentView === 'month' ? 'primary' : ''"
          >
            月视图
          </el-button>
          <el-button
            @click="changeView('week')"
            :type="currentView === 'week' ? 'primary' : ''"
          >
            周视图
          </el-button>
          <el-button
            @click="changeView('day')"
            :type="currentView === 'day' ? 'primary' : ''"
          >
            日视图
          </el-button>
        </el-button-group>

        <div class="date-navigation">
          <el-button @click="prevPeriod" icon="ArrowLeft" />
          <span class="current-period">{{ currentPeriodText }}</span>
          <el-button @click="nextPeriod" icon="ArrowRight" />
          <el-button @click="goToday">今天</el-button>
        </div>

        <div class="calendar-actions">
          <el-button type="primary" @click="showGenerateDialog">
            <el-icon><MagicStick /></el-icon>
            生成排班
          </el-button>
          <el-button type="success" @click="showSmartGenerateDialog">
            <el-icon><Opportunity /></el-icon>
            AI智能排班
          </el-button>
          <el-button @click="exportSchedule">
            <el-icon><Document /></el-icon>
            导出排班
          </el-button>
          <el-button @click="refreshData">
            <el-icon><Refresh /></el-icon>
            刷新
          </el-button>
        </div>
      </div>
    </div>

    <!-- 筛选条件 -->
    <div class="filter-card">
      <div class="filter-row">
        <div class="filter-item">
          <div class="filter-label">科室/部门</div>
          <el-select
            v-model="filters.department_id"
            placeholder="请选择科室"
            clearable
            @change="handleFilterChange"
          >
            <el-option
              v-for="dept in departmentOptions"
              :key="dept.value"
              :label="dept.label"
              :value="dept.value"
            />
          </el-select>
        </div>

        <div class="filter-item">
          <div class="filter-label">人员类型</div>
          <el-select
            v-model="filters.staff_type"
            placeholder="请选择类型"
            clearable
            @change="handleFilterChange"
          >
            <el-option
              v-for="type in staffTypeOptions"
              :key="type.value"
              :label="type.label"
              :value="type.value"
            />
          </el-select>
        </div>

        <div class="filter-item">
          <div class="filter-label">排班日期</div>
          <el-date-picker
            v-model="filters.date_range"
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            @change="handleFilterChange"
          />
        </div>

        <div class="filter-item">
          <div class="filter-label">排班状态</div>
          <el-select
            v-model="filters.status"
            placeholder="请选择状态"
            clearable
            @change="handleFilterChange"
          >
            <el-option label="全部" value="" />
            <el-option label="正常" :value="1" />
            <el-option label="取消" :value="0" />
            <el-option label="调班" :value="2" />
            <el-option label="请假" :value="3" />
          </el-select>
        </div>

        <div class="filter-item">
          <div class="filter-label">班次时间</div>
          <el-select
            v-model="filters.time_slot"
            placeholder="请选择班次"
            clearable
            @change="handleFilterChange"
          >
            <el-option
              v-for="slot in timeSlotOptions"
              :key="slot.value"
              :label="slot.label"
              :value="slot.value"
            />
          </el-select>
        </div>
      </div>

      <div class="filter-actions">
        <el-button @click="resetFilters">重置</el-button>
        <el-button type="primary" @click="loadScheduleInstances"
          >查询</el-button
        >
      </div>
    </div>

    <!-- 月视图 -->
    <div v-if="currentView === 'month'" class="month-view">
      <div class="month-grid">
        <div class="month-header">
          <div class="weekday-header" v-for="day in weekDays" :key="day">
            {{ day }}
          </div>
        </div>
        <div class="month-body">
          <div
            v-for="(week, weekIndex) in monthWeeks"
            :key="weekIndex"
            class="week-row"
          >
            <div
              v-for="day in week"
              :key="day.date"
              class="day-cell"
              :class="{
                'current-month': day.isCurrentMonth,
                today: day.isToday,
                weekend: day.isWeekend,
                'has-schedules': getSchedulesForDate(day.date).length > 0,
              }"
              @click="handleDayClick(day)"
            >
              <div class="day-header">
                <span class="day-number">{{ day.day }}</span>
                <span v-if="day.isToday" class="today-badge">今</span>
                <span
                  class="schedule-count"
                  v-if="getSchedulesForDate(day.date).length > 0"
                >
                  {{ getSchedulesForDate(day.date).length }}
                </span>
              </div>
              <div class="schedule-items">
                <div
                  v-for="schedule in getSchedulesForDate(day.date).slice(0, 3)"
                  :key="schedule.instance_id"
                  class="schedule-item"
                  :class="getScheduleStatusClass(schedule)"
                  @click.stop="viewScheduleDetails(schedule)"
                >
                  <div class="schedule-time">
                    {{ formatTimeSlot(schedule.time_slot_code) }}
                  </div>
                  <div class="schedule-staff">{{ schedule.staff_name }}</div>
                </div>
                <div
                  v-if="getSchedulesForDate(day.date).length > 3"
                  class="schedule-more"
                  @click.stop="showDaySchedules(day)"
                >
                  +{{ getSchedulesForDate(day.date).length - 3 }}更多
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 周视图 -->
    <div v-else-if="currentView === 'week'" class="week-view">
      <div class="week-grid">
        <div class="time-column">
          <div class="time-header">时间</div>
          <div
            v-for="timeSlot in timeSlots"
            :key="timeSlot.value"
            class="time-slot"
          >
            {{ timeSlot.label }}
          </div>
        </div>
        <div
          v-for="day in weekDaysData"
          :key="day.date"
          class="day-column"
          :class="{ weekend: day.isWeekend, today: day.isToday }"
        >
          <div class="day-header">
            <div class="date-info">
              <div class="weekday">{{ day.weekday }}</div>
              <div class="date">{{ day.date }}</div>
            </div>
          </div>
          <div class="day-schedules">
            <div
              v-for="timeSlot in timeSlots"
              :key="timeSlot.value"
              class="schedule-cell"
              :class="{
                'has-schedule':
                  getSchedulesForDateTime(day.fullDate, timeSlot.value).length >
                  0,
              }"
            >
              <div
                v-for="schedule in getSchedulesForDateTime(
                  day.fullDate,
                  timeSlot.value
                )"
                :key="schedule.instance_id"
                class="schedule-item"
                :class="getScheduleStatusClass(schedule)"
                @click="viewScheduleDetails(schedule)"
              >
                <div class="staff-name">{{ schedule.staff_name }}</div>
                <div class="schedule-type">
                  {{ formatScheduleType(schedule.schedule_type) }}
                </div>
                <div class="schedule-location">
                  {{ getScheduleLocation(schedule) }}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 日视图 -->
    <div v-else class="day-view">
      <div class="day-header">
        <h3>{{ currentDayText }}</h3>
        <div class="day-stats">
          <span class="stat-item"
            >总排班: {{ getSchedulesForDate(currentDayDate).length }}</span
          >
          <span class="stat-item"
            >正常: {{ getSchedulesByStatus(1).length }}</span
          >
          <span class="stat-item"
            >调班: {{ getSchedulesByStatus(2).length }}</span
          >
          <span class="stat-item"
            >请假: {{ getSchedulesByStatus(3).length }}</span
          >
        </div>
      </div>
      <div class="day-timeline">
        <div v-for="hour in dayHours" :key="hour" class="hour-row">
          <div class="hour-label">{{ hour }}:00</div>
          <div class="hour-schedules">
            <div
              v-for="schedule in getSchedulesForHour(currentDayDate, hour)"
              :key="schedule.instance_id"
              class="schedule-block"
              :class="getScheduleStatusClass(schedule)"
              :style="getScheduleBlockStyle(schedule)"
              @click="viewScheduleDetails(schedule)"
            >
              <div class="schedule-content">
                <div class="schedule-time">
                  {{ formatTimeRange(schedule.time_slot_code) }}
                </div>
                <div class="schedule-staff">{{ schedule.staff_name }}</div>
                <div class="schedule-type">
                  {{ formatScheduleType(schedule.schedule_type) }}
                </div>
                <div class="schedule-location">
                  {{ getScheduleLocation(schedule) }}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 排班详情对话框 -->
    <el-dialog
      v-model="detailDialog.visible"
      :title="`排班详情 - ${
        selectedSchedule
          ? formatDisplayDate(selectedSchedule.schedule_date)
          : ''
      }`"
      width="700px"
      :destroy-on-close="true"
    >
      <div v-if="selectedSchedule" class="schedule-detail">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="人员信息" span="2">
            <div class="staff-info">
              <el-avatar :size="40" :src="selectedSchedule.avatar">
                <span class="avatar-text">{{
                  getStaffTypeIcon(selectedSchedule.staff_type)
                }}</span>
              </el-avatar>
              <div class="staff-details">
                <div class="staff-name">{{ selectedSchedule.staff_name }}</div>
                <div class="staff-meta">
                  {{ formatStaffType(selectedSchedule.staff_type) }} ·
                  {{ selectedSchedule.department_name }}
                  <el-tag
                    v-if="selectedSchedule.professional_title"
                    size="small"
                    effect="plain"
                  >
                    {{ selectedSchedule.professional_title }}
                  </el-tag>
                </div>
              </div>
            </div>
          </el-descriptions-item>

          <el-descriptions-item label="排班日期">
            {{ formatDisplayDate(selectedSchedule.schedule_date) }}
            <el-tag
              v-if="isToday(selectedSchedule.schedule_date)"
              type="success"
              size="small"
              >今天</el-tag
            >
            <el-tag
              v-else-if="isPastDate(selectedSchedule.schedule_date)"
              type="info"
              size="small"
              >已过</el-tag
            >
            <el-tag v-else type="warning" size="small">未来</el-tag>
          </el-descriptions-item>

          <el-descriptions-item label="班次时间">
            {{ formatTimeSlot(selectedSchedule.time_slot_code) }}
            <br />
            <small class="time-range">{{
              formatTimeRange(selectedSchedule.time_slot_code)
            }}</small>
          </el-descriptions-item>

          <el-descriptions-item label="排班类型">
            <el-tag :type="getScheduleTypeTag(selectedSchedule.schedule_type)">
              {{ formatScheduleType(selectedSchedule.schedule_type) }}
            </el-tag>
          </el-descriptions-item>

          <el-descriptions-item label="工作地点">
            {{ getScheduleLocation(selectedSchedule) }}
          </el-descriptions-item>

          <el-descriptions-item label="状态">
            <el-tag :type="getStatusTagType(selectedSchedule.status)">
              {{ formatStatus(selectedSchedule.status) }}
            </el-tag>
          </el-descriptions-item>
        </el-descriptions>

        <!-- 业务信息 -->
        <div
          v-if="requiresBusinessInfo(selectedSchedule.schedule_type)"
          class="business-info-section"
        >
          <h4>业务信息</h4>
          <el-descriptions :column="1" border>
            <template v-if="selectedSchedule.schedule_type === 'outpatient'">
              <el-descriptions-item label="费用项目">
                {{ selectedSchedule.fee_item_name || "-" }}
                <span v-if="selectedSchedule.fee_amount" class="fee-amount">
                  (¥{{ formatAmount(selectedSchedule.fee_amount) }})
                </span>
                <!-- 添加费用来源提示 -->
                <el-tag
                  v-if="selectedSchedule.template_id"
                  size="small"
                  type="info"
                >
                  来自模板
                </el-tag>
              </el-descriptions-item>
              <el-descriptions-item label="最大挂号数">
                {{ selectedSchedule.max_patients }}
              </el-descriptions-item>
              <el-descriptions-item label="实际挂号数">
                <el-tag :type="getPatientCountType(selectedSchedule)">
                  {{ selectedSchedule.actual_patients || 0 }}
                </el-tag>
                <span
                  v-if="selectedSchedule.max_patients"
                  class="patient-ratio"
                >
                  ({{
                    Math.round(
                      ((selectedSchedule.actual_patients || 0) /
                        selectedSchedule.max_patients) *
                        100
                    )
                  }}%)
                </span>
              </el-descriptions-item>
            </template>
            <template v-else-if="selectedSchedule.schedule_type === 'pharmacy'">
              <el-descriptions-item label="药房位置">
                {{ selectedSchedule.pharmacy_location || "-" }}
              </el-descriptions-item>
              <el-descriptions-item label="服务类型">
                {{ selectedSchedule.service_type || "-" }}
              </el-descriptions-item>
            </template>
            <template
              v-else-if="
                ['billing', 'registration'].includes(
                  selectedSchedule.schedule_type
                )
              "
            >
              <el-descriptions-item label="窗口编号">
                {{ selectedSchedule.window_number || "-" }}
              </el-descriptions-item>
              <el-descriptions-item label="服务范围">
                {{ selectedSchedule.service_scope || "-" }}
              </el-descriptions-item>
            </template>
          </el-descriptions>
        </div>

        <!-- 备注信息 -->
        <div v-if="selectedSchedule.notes" class="notes-section">
          <h4>备注信息</h4>
          <div class="notes-content">{{ selectedSchedule.notes }}</div>
        </div>

        <!-- 操作按钮 -->
        <div
          class="action-buttons"
          style="margin-top: 20px; text-align: center"
        >
          <el-button
            v-if="
              selectedSchedule.status === 1 &&
              !isPastDate(selectedSchedule.schedule_date)
            "
            type="warning"
            @click="showAdjustDialog(selectedSchedule)"
          >
            <el-icon><Switch /></el-icon>
            调班
          </el-button>
          <el-button
            v-if="
              selectedSchedule.status === 1 &&
              !isPastDate(selectedSchedule.schedule_date)
            "
            type="danger"
            @click="showLeaveDialog(selectedSchedule)"
          >
            <el-icon><Clock /></el-icon>
            请假
          </el-button>
          <el-button
            v-if="
              selectedSchedule.status === 1 &&
              !isPastDate(selectedSchedule.schedule_date)
            "
            type="info"
            @click="showCancelDialog(selectedSchedule)"
          >
            <el-icon><Close /></el-icon>
            取消
          </el-button>
          <el-button
            v-if="
              selectedSchedule.status !== 1 &&
              !isPastDate(selectedSchedule.schedule_date)
            "
            type="success"
            @click="restoreSchedule(selectedSchedule)"
          >
            <el-icon><Check /></el-icon>
            恢复
          </el-button>
          <el-button type="primary" @click="showEditDialog(selectedSchedule)">
            <el-icon><Edit /></el-icon>
            编辑
          </el-button>
        </div>
      </div>
    </el-dialog>

    <!-- 生成排班对话框 --封装成组件 -->
    <schedule-generator
      v-model:visible="generateDialog.visible"
      :department-options="departmentOptions"
      :staff-type-options="staffTypeOptions"
      :schedule-type-options="scheduleTypeOptions"
      :schedule-templates="scheduleTemplates"
      :time-slot-list="timeSlotList"
      @confirm="handleGenerateConfirm"
      @cancel="handleGenerateCancel"
    />

    <!-- 智能排班对话框 --封装成组件 -->
    <smart-schedule-generator
      v-model:visible="smartGenerateDialog.visible"
      :department-options="departmentOptions"
      :staff-type-options="staffTypeOptions"
      :time-slot-options="timeSlotOptions"
      :schedule-type-options="scheduleTypeOptions"
      :all-staff-list="allStaffList"
      :current-schedule-instances="scheduleInstances"
      :department-list="departmentList"
      :time-slot-list="timeSlotList"
      :schedule-type-list="sheduleTypeList"
      :schedule-templates="scheduleTemplates" 
      @confirm="handleSmartGenerateConfirm"
      @cancel="handleSmartGenerateCancel"
    />

    <!-- 调班对话框 -->
    <el-dialog v-model="adjustDialog.visible" title="调班操作" width="600px">
      <div v-if="adjustDialog.schedule" class="adjust-dialog">
        <el-alert
          title="调班操作说明"
          description="将当前排班调整给其他人员，原排班状态将标记为'调班'"
          type="info"
          show-icon
          style="margin-bottom: 20px"
        />

        <el-descriptions :column="1" border>
          <el-descriptions-item label="原排班信息">
            {{ adjustDialog.schedule.staff_name }} -
            {{ formatTimeSlot(adjustDialog.schedule.time_slot_code) }} -
            {{ getScheduleLocation(adjustDialog.schedule) }}
          </el-descriptions-item>
          <el-descriptions-item label="排班日期">
            {{ formatDisplayDate(adjustDialog.schedule.schedule_date) }}
          </el-descriptions-item>
        </el-descriptions>

        <el-form
          :model="adjustForm"
          label-width="100px"
          style="margin-top: 20px"
        >
          <el-form-item label="调整至人员" prop="target_staff_id">
            <el-select
              v-model="adjustForm.target_staff_id"
              placeholder="请选择接替人员"
              style="width: 100%"
              filterable
            >
              <el-option
                v-for="staff in availableStaffOptions"
                :key="staff.value"
                :label="staff.label"
                :value="staff.value"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="调整原因" prop="reason">
            <el-input
              v-model="adjustForm.reason"
              type="textarea"
              :rows="3"
              placeholder="请输入调班原因"
            />
          </el-form-item>
          <el-form-item label="通知原人员">
            <el-switch v-model="adjustForm.notify_original" />
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <el-button @click="adjustDialog.visible = false">取消</el-button>
        <el-button
          type="primary"
          @click="confirmAdjust"
          :loading="adjustLoading"
        >
          确认调班
        </el-button>
      </template>
    </el-dialog>

    <!-- 请假对话框 -->
    <el-dialog v-model="leaveDialog.visible" title="请假申请" width="500px">
      <div v-if="leaveDialog.schedule" class="leave-dialog">
        <el-form
          :model="leaveForm"
          label-width="100px"
          :rules="leaveRules"
          ref="leaveFormRef"
        >
          <el-form-item label="请假类型" prop="leave_type">
            <el-select
              v-model="leaveForm.leave_type"
              placeholder="请选择请假类型"
              style="width: 100%"
            >
              <el-option label="病假" value="sick" />
              <el-option label="事假" value="personal" />
              <el-option label="年假" value="annual" />
              <el-option label="调休" value="compensatory" />
              <el-option label="其他" value="other" />
            </el-select>
          </el-form-item>
          <el-form-item label="开始时间" prop="start_time">
            <el-time-picker
              v-model="leaveForm.start_time"
              placeholder="开始时间"
              style="width: 100%"
              value-format="HH:mm:ss"
            />
          </el-form-item>
          <el-form-item label="结束时间" prop="end_time">
            <el-time-picker
              v-model="leaveForm.end_time"
              placeholder="结束时间"
              style="width: 100%"
              value-format="HH:mm:ss"
            />
          </el-form-item>
          <el-form-item label="请假原因" prop="reason">
            <el-input
              v-model="leaveForm.reason"
              type="textarea"
              :rows="3"
              placeholder="请输入请假原因"
            />
          </el-form-item>
          <el-form-item label="证明材料">
            <el-upload
              action="#"
              :auto-upload="false"
              :on-change="handleLeaveFileChange"
              :file-list="leaveForm.files"
              list-type="text"
            >
              <el-button type="primary">点击上传</el-button>
              <template #tip>
                <div class="el-upload__tip">请上传相关证明文件，如病假条等</div>
              </template>
            </el-upload>
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <el-button @click="leaveDialog.visible = false">取消</el-button>
        <el-button type="primary" @click="confirmLeave" :loading="leaveLoading">
          提交申请
        </el-button>
      </template>
    </el-dialog>

    <!-- 日排班列表对话框 -->
    <el-dialog
      v-model="daySchedulesDialog.visible"
      :title="`${
        daySchedulesDialog.date
          ? formatDisplayDate(daySchedulesDialog.date)
          : ''
      } 排班列表`"
      width="800px"
    >
      <div v-if="daySchedulesDialog.date" class="day-schedules-list">
        <el-table :data="getSchedulesForDate(daySchedulesDialog.date)" stripe>
          <el-table-column label="人员信息" min-width="180">
            <template #default="{ row }">
              <div class="staff-info-cell">
                <el-avatar :size="32" :src="row.avatar">
                  <span class="avatar-text">{{
                    getStaffTypeIcon(row.staff_type)
                  }}</span>
                </el-avatar>
                <div class="staff-details">
                  <div class="staff-name">{{ row.staff_name }}</div>
                  <div class="staff-meta">
                    {{ formatStaffType(row.staff_type) }} ·
                    {{ row.department_name }}
                  </div>
                </div>
              </div>
            </template>
          </el-table-column>
          <el-table-column label="班次时间" width="120">
            <template #default="{ row }">
              <el-tag :type="getShiftType(row.time_slot_code)" size="small">
                {{ formatTimeSlot(row.time_slot_code) }}
              </el-tag>
              <div class="time-range">
                {{ formatTimeRange(row.time_slot_code) }}
              </div>
            </template>
          </el-table-column>
          <el-table-column label="排班类型" width="100">
            <template #default="{ row }">
              <el-tag
                :type="getScheduleTypeTag(row.schedule_type)"
                size="small"
              >
                {{ formatScheduleType(row.schedule_type) }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="工作地点" width="150">
            <template #default="{ row }">
              {{ getScheduleLocation(row) }}
            </template>
          </el-table-column>
          <el-table-column label="状态" width="80">
            <template #default="{ row }">
              <el-tag :type="getStatusTagType(row.status)" size="small">
                {{ formatStatus(row.status) }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="120" fixed="right">
            <template #default="{ row }">
              <el-button size="small" @click="viewScheduleDetails(row)"
                >详情</el-button
              >
            </template>
          </el-table-column>
        </el-table>

        <div
          class="day-summary"
          style="
            margin-top: 20px;
            padding: 16px;
            background: #f5f7fa;
            border-radius: 4px;
          "
        >
          <h4>当日排班统计</h4>
          <el-row :gutter="20">
            <el-col :span="6">
              <div class="summary-item">
                <div class="summary-label">总排班数</div>
                <div class="summary-value">
                  {{ getSchedulesForDate(daySchedulesDialog.date).length }}
                </div>
              </div>
            </el-col>
            <el-col :span="6">
              <div class="summary-item">
                <div class="summary-label">正常</div>
                <div class="summary-value success">
                  {{
                    getSchedulesByStatusForDate(daySchedulesDialog.date, 1)
                      .length
                  }}
                </div>
              </div>
            </el-col>
            <el-col :span="6">
              <div class="summary-item">
                <div class="summary-label">调班</div>
                <div class="summary-value warning">
                  {{
                    getSchedulesByStatusForDate(daySchedulesDialog.date, 2)
                      .length
                  }}
                </div>
              </div>
            </el-col>
            <el-col :span="6">
              <div class="summary-item">
                <div class="summary-label">请假</div>
                <div class="summary-value danger">
                  {{
                    getSchedulesByStatusForDate(daySchedulesDialog.date, 3)
                      .length
                  }}
                </div>
              </div>
            </el-col>
          </el-row>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, computed, nextTick, watch } from "vue";
import { ElMessage, ElMessageBox } from "element-plus";
import { useStore } from "vuex";
// 导入子组件
import ScheduleGenerator from "@/components/manager/scheduleInstances/ScheduleGenerator.vue";
import SmartScheduleGenerator from "@/components/manager/scheduleInstances/SmartScheduleGenerator.vue";

// ==================== 引入真实API接口数据 ====================
import {
  getDepartmentList, // 预加载所有科室列表
  getStaffTypeList, // 预加载所有人员类型列表
  getTimeSlotList, // 预加载班次时间列表
  getScheduleTypeList, // 预加载排班类型列表
  getDoctorList, // 新增：获取医生列表
  getNurseList, // 新增：获取护士列表
  getPharmacistList, // 新增：获取药剂师列表
  getFinanceStaffList, // 新增：获取财务人员列表
  getFeeItemList, // 新增：获取费用项目列表
  getScheduleTemplateList, // 新增：获取排班模板列表
  generateScheduleInstances, // 生成排班实例
  getScheduleInstanceDataBySearch, //根据查询条件加载排班实例数据
} from "@/api/api";

// ==================== 组件状态管理 ====================
const currentView = ref("month"); // 当前视图模式: month/week/day
const currentDate = ref(new Date()); // 当前显示的日期
const loading = ref(false); // 加载状态
const store = useStore();

// ==================== 筛选条件 ====================
const filters = reactive({
  department_id: "",
  staff_type: "",
  date_range: [],
  status: "",
  time_slot: "",
});

// ==================== 数据存储 ====================
const scheduleInstances = ref([]); // 排班实例数据
const departmentList = ref([]); // 预加载所有科室列表
const allDepartmentOptions = ref([]);
const filteredDepartmentOptions = ref([]);
const departmentOptions = ref([]); // 科室选项
const staffTypeOptions = ref([]); // 人员类型选项
const timeSlotList = ref([]); // 预加载班次时间列表数据
const sheduleTypeList = ref([]); //预加载排班类型类别数据
const timeSlotOptions = ref([]); // 班次时间选项
const availableStaffOptions = ref([]); // 可用人员选项（用于调班）
const feeItemsList = ref([]); // 存储所有费用项目数据
// 添加模板数据存储
const scheduleTemplates = ref([]);
// 人员数据存储
const staffData = reactive({
  doctors: [], // 医生列表
  nurses: [], // 护士列表
  pharmacists: [], // 药剂师列表
  financeStaff: [], // 财务人员列表
  managers: [], // 管理员列表
});

// 完整人员列表（合并所有类型）
const allStaffList = computed(() => {
  return [
    ...staffData.doctors.map((staff) => ({ ...staff, staff_type: "doctor" })),
    ...staffData.nurses.map((staff) => ({ ...staff, staff_type: "nurse" })),
    ...staffData.pharmacists.map((staff) => ({
      ...staff,
      staff_type: "pharmacist",
    })),
    ...staffData.financeStaff.map((staff) => ({
      ...staff,
      staff_type: "finance",
    })),
    ...staffData.managers.map((staff) => ({ ...staff, staff_type: "manager" })),
  ];
});

// ==================== 对话框控制 ====================
const detailDialog = reactive({ visible: false });
const generateDialog = reactive({ visible: false });
const smartGenerateDialog = reactive({ visible: false });
const adjustDialog = reactive({ visible: false });
const leaveDialog = reactive({ visible: false });
const daySchedulesDialog = reactive({ visible: false, date: null });

// ==================== 表单数据 ====================
const selectedSchedule = ref(null); // 当前选中的排班

const generateForm = reactive({
  date_range: [],
  departments: [],
  staff_types: [],
  schedule_types: [], // 新增：排班类型
  overwrite_strategy: "skip",
  exclude_holidays: true,
  notes: "",
});

const smartGenerateForm = reactive({
  month: "",
  overwrite: false,
});

const adjustForm = reactive({
  target_staff_id: "",
  reason: "",
  notify_original: true,
});

const leaveForm = reactive({
  leave_type: "",
  start_time: "",
  end_time: "",
  reason: "",
  files: [],
});

// ==================== 加载状态 ====================
const generateLoading = ref(false);
const adjustLoading = ref(false);
const leaveLoading = ref(false);

// ==================== 表单引用 ====================
const generateFormRef = ref(null);
const leaveFormRef = ref(null);

// ==================== 表单验证规则 ====================
const leaveRules = {
  leave_type: [
    { required: true, message: "请选择请假类型", trigger: "change" },
  ],
  reason: [{ required: true, message: "请输入请假原因", trigger: "blur" }],
};

// ==================== 人员类型与排班类型映射关系 ====================
const staffTypeScheduleMap = {
  doctor: [
    "outpatient",
    "inpatient",
    "emergency",
    "surgery",
    "consultation",
    "examination",
  ],
  nurse: ["inpatient", "outpatient", "service"],
  pharmacist: ["pharmacy"],
  finance: ["billing", "registration", "office"],
  administrative: ["office"],
  manager: ["office"],
  logistics: ["service"],
};

// ==================== 计算属性 ====================

/**
 * 当前周期文本显示（月视图/周视图/日视图）
 */
const currentPeriodText = computed(() => {
  if (currentView.value === "month") {
    return currentDate.value.toLocaleDateString("zh-CN", {
      year: "numeric",
      month: "long",
    });
  } else if (currentView.value === "week") {
    const startOfWeek = getStartOfWeek(currentDate.value);
    const endOfWeek = new Date(startOfWeek);
    endOfWeek.setDate(startOfWeek.getDate() + 6);
    return `${formatDisplayDate(startOfWeek)} - ${formatDisplayDate(
      endOfWeek
    )}`;
  } else {
    return currentDate.value.toLocaleDateString("zh-CN", {
      year: "numeric",
      month: "long",
      day: "numeric",
      weekday: "long",
    });
  }
});

/**
 * 当前日期文本（日视图使用）
 */
const currentDayText = computed(() => {
  return currentDate.value.toLocaleDateString("zh-CN", {
    year: "numeric",
    month: "long",
    day: "numeric",
    weekday: "long",
  });
});

/**
 * 当前日期（YYYY-MM-DD格式）
 */
const currentDayDate = computed(() => {
  return formatDate(currentDate.value);
});

/**
 * 月视图的周数据生成
 */
const monthWeeks = computed(() => {
  const year = currentDate.value.getFullYear();
  const month = currentDate.value.getMonth();
  const firstDay = new Date(year, month, 1);
  const lastDay = new Date(year, month + 1, 0);

  const weeks = [];
  let currentWeek = [];

  // 填充上个月的日期
  const startDay = firstDay.getDay() === 0 ? 6 : firstDay.getDay() - 1; // 周一开始
  for (let i = startDay - 1; i >= 0; i--) {
    const date = new Date(year, month, -i);
    currentWeek.push(createDayData(date, false));
  }

  // 填充当前月的日期
  for (let day = 1; day <= lastDay.getDate(); day++) {
    const date = new Date(year, month, day);
    currentWeek.push(createDayData(date, true));

    if (currentWeek.length === 7) {
      weeks.push([...currentWeek]);
      currentWeek = [];
    }
  }

  // 填充下个月的日期
  if (currentWeek.length > 0) {
    let nextMonthDay = 1;
    while (currentWeek.length < 7) {
      const date = new Date(year, month + 1, nextMonthDay++);
      currentWeek.push(createDayData(date, false));
    }
    weeks.push([...currentWeek]);
  }

  return weeks;
});

/**
 * 周视图的日期数据
 */
const weekDaysData = computed(() => {
  const startOfWeek = getStartOfWeek(currentDate.value);
  const days = [];

  for (let i = 0; i < 7; i++) {
    const date = new Date(startOfWeek);
    date.setDate(startOfWeek.getDate() + i);
    days.push({
      fullDate: formatDate(date),
      date: date.getDate(),
      weekday: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"][
        date.getDay()
      ],
      isWeekend: date.getDay() === 0 || date.getDay() === 6,
      isToday: isToday(date),
    });
  }

  return days;
});

/**
 * 可用的排班类型（根据选中的人员类型过滤）
 */
const availableScheduleTypes = computed(() => {
  if (!generateForm.staff_types.length) {
    return [];
  }

  // 获取所有选中人员类型对应的排班类型
  const allowedTypes = new Set();
  generateForm.staff_types.forEach((staffType) => {
    const types = staffTypeScheduleMap[staffType] || [];
    types.forEach((type) => allowedTypes.add(type));
  });

  // 从排班类型列表中过滤
  return scheduleTypeOptions.value.filter((option) =>
    allowedTypes.has(option.value)
  );
});

/**
 * 是否可以生成排班
 */
const canGenerate = computed(() => {
  return (
    generateForm.staff_types.length > 0 &&
    generateForm.schedule_types.length > 0 &&
    generateForm.date_range.length === 2
  );
});

// 统一获取日期范围的函数
const getDateRangeByView = (viewType, currentDate) => {
  let startDate, endDate, date;

  switch (viewType) {
    case "month":
      startDate = new Date(
        currentDate.getFullYear(),
        currentDate.getMonth(),
        1
      );
      endDate = new Date(
        currentDate.getFullYear(),
        currentDate.getMonth() + 1,
        0
      );
      date = formatDate(currentDate).slice(0, 7); // YYYY-MM
      break;

    case "week":
      startDate = getStartOfWeek(currentDate);
      endDate = new Date(startDate);
      endDate.setDate(startDate.getDate() + 6);
      date = formatDate(startDate);
      break;

    case "day":
      startDate = new Date(currentDate);
      endDate = new Date(currentDate);
      date = formatDate(currentDate);
      break;

    default:
      startDate = new Date(currentDate);
      endDate = new Date(currentDate);
      date = formatDate(currentDate);
  }

  return {
    start_date: formatDate(startDate),
    end_date: formatDate(endDate),
    date: date,
  };
};

// ==================== 常量数据 ====================
const weekDays = ["周一", "周二", "周三", "周四", "周五", "周六", "周日"];
// ==================== 使用预加载的班次时间数据 ====================
const timeSlots = computed(() => {
  return timeSlotList.value.map((type) => ({
    value: type.slot_code,
    label: type.slot_name + "(" + type.start_time + "-" + type.end_time + ")",
  }));
});

const dayHours = Array.from({ length: 24 }, (_, i) => i); // 0-23小时

// 排班类型选项
const scheduleTypeOptions = computed(() => {
  return sheduleTypeList.value.map((type) => ({
    value: type.type_code,
    label: type.type_name,
  }));
});

// ==================== 核心方法 ====================

/**
 * 切换视图模式
 * @param {string} view - 视图模式: month/week/day
 */
const changeView = (view) => {
  currentView.value = view;
  loadScheduleInstances();
};

/**
 * 切换到上一个周期
 */
const prevPeriod = () => {
  if (currentView.value === "month") {
    currentDate.value = new Date(
      currentDate.value.getFullYear(),
      currentDate.value.getMonth() - 1,
      1
    );
  } else if (currentView.value === "week") {
    currentDate.value = new Date(
      currentDate.value.getTime() - 7 * 24 * 60 * 60 * 1000
    );
  } else {
    currentDate.value = new Date(
      currentDate.value.getTime() - 24 * 60 * 60 * 1000
    );
  }
  loadScheduleInstances();
};

/**
 * 切换到下一个周期
 */
const nextPeriod = () => {
  if (currentView.value === "month") {
    currentDate.value = new Date(
      currentDate.value.getFullYear(),
      currentDate.value.getMonth() + 1,
      1
    );
  } else if (currentView.value === "week") {
    currentDate.value = new Date(
      currentDate.value.getTime() + 7 * 24 * 60 * 60 * 1000
    );
  } else {
    currentDate.value = new Date(
      currentDate.value.getTime() + 24 * 60 * 60 * 1000
    );
  }
  console.log("切换后日期:", currentDate.value);
  loadScheduleInstances();
};

/**
 * 跳转到今天
 */
const goToday = () => {
  currentDate.value = new Date();
  loadScheduleInstances();
};

/**
 * 处理筛选条件变化
 */
const handleFilterChange = () => {
  loadScheduleInstances();
};

/**
 * 重置筛选条件
 */
const resetFilters = () => {
  filters.department_id = "";
  filters.staff_type = "";
  filters.date_range = [];
  filters.status = "";
  filters.time_slot = "";
  loadScheduleInstances();
};

//=============加载排班实例请求============

/**
 * 加载排班实例数据-月视图-周视图-日视图
 * TODO: 替换为真实API调用
 */
const loadScheduleInstances = async () => {
  loading.value = true;
  //加载请求参数
  let loadScheduleRequest = {
    department_id: filters.department_id,
    staff_type: filters.staff_type,
    date_range: filters.date_range,
    status: filters.status,
    time_slot: filters.time_slot,
    view_type: currentView.value,
    // 日期范围参数
    ...getDateRangeByView(currentView.value, currentDate.value),
  };
  //console.log("请求参数：", loadScheduleRequest);

  try {
    // 调用API接口
    const response = await getScheduleInstanceDataBySearch(loadScheduleRequest);
    //console.log(response);

    let filteredData = [];

    if (response && response.code == 200) {
      //console.log("加载排班实例数据列表："+response.data);
      filteredData = response.data;
    }

    //取出数据后再筛选
    if (filters.department_id) {
      filteredData = filteredData.filter(
        (item) => String(item.department_id) === String(filters.department_id)
      );
    }

    if (filters.staff_type) {
      filteredData = filteredData.filter(
        (item) => item.staff_type === filters.staff_type
      );
    }

    if (filters.date_range && filters.date_range.length === 2) {
      const [start, end] = filters.date_range;
      filteredData = filteredData.filter((item) => {
        const scheduleDate = new Date(item.schedule_date);
        return scheduleDate >= new Date(start) && scheduleDate <= new Date(end);
      });
    }

    if (filters.status !== "") {
      filteredData = filteredData.filter(
        (item) => item.status === filters.status
      );
    }

    if (filters.time_slot) {
      filteredData = filteredData.filter(
        (item) => item.time_slot_code === filters.time_slot
      );
    }

    scheduleInstances.value = filteredData;
  } catch (error) {
    console.error("加载排班实例失败:", error);
    ElMessage.error("加载排班数据失败");
  } finally {
    loading.value = false;
  }
};

// ==================== 排班生成相关方法 ====================

// ==================== 创建排班实例核心方法 ====================

/**
 * 根据排班类型和科室信息获取工作地点
 */
const getLocationByType = (scheduleType, departmentInfo = null) => {
  const typeConfig = sheduleTypeList.value.find(
    (item) => item.type_code === scheduleType
  );
  if (!typeConfig) return "工作区域";

  const defaultLocation = typeConfig.default_location || "工作区域";

  switch (typeConfig.location_type) {
    case "department_based":
      if (departmentInfo && departmentInfo.department_name) {
        return `${departmentInfo.department_name}${defaultLocation}`;
      }
      return defaultLocation;

    case "fixed":
      return defaultLocation;

    case "custom":
      // 自定义类型，可能需要额外的逻辑处理
      return defaultLocation;

    default:
      return defaultLocation;
  }
};

/**
 * 在排班详情中使用的封装方法
 */
const getScheduleLocation = (schedule) => {
  const departmentInfo = {
    department_name: schedule.department_name,
  };
  return getLocationByType(schedule.schedule_type, departmentInfo);
};

/**
 * 根据状态生成备注信息
 */
const getStatusNotes = (status) => {
  const notesMap = {
    2: "因人员调整临时调班",
    3: "因病请假",
  };
  return notesMap[status] || "";
};

// ==================== 数据查询方法 ====================

/**
 * 获取指定日期的排班列表
 */
const getSchedulesForDate = (date) => {
  return scheduleInstances.value.filter(
    (schedule) => schedule.schedule_date === date
  );
};

/**
 * 获取指定日期和班次的排班列表
 */
const getSchedulesForDateTime = (date, timeSlot) => {
  return scheduleInstances.value.filter(
    (schedule) =>
      schedule.schedule_date === date && schedule.time_slot_code === timeSlot
  );
};

/**
 * 获取指定日期小时的排班列表（日视图使用）
 */
const getSchedulesForHour = (date, hour) => {
  // 简化实现：返回该日期所有排班，实际应根据时间范围过滤
  return getSchedulesForDate(date).filter((schedule) => {
    const timeRange = getTimeSlotRange(schedule.time_slot_code);
    return timeRange && hour >= timeRange.startHour && hour < timeRange.endHour;
  });
};

/**
 * 根据状态筛选排班列表
 */
const getSchedulesByStatus = (status) => {
  return scheduleInstances.value.filter(
    (schedule) => schedule.status === status
  );
};

/**
 * 获取指定日期和状态的排班列表
 */
const getSchedulesByStatusForDate = (date, status) => {
  return getSchedulesForDate(date).filter(
    (schedule) => schedule.status === status
  );
};

// ==================== 视图交互方法 ====================

/**
 * 查看排班详情
 */
const viewScheduleDetails = (schedule) => {
  selectedSchedule.value = schedule;
  detailDialog.visible = true;
};

/**
 * 处理日期点击事件
 */
const handleDayClick = (day) => {
  if (getSchedulesForDate(day.date).length > 0) {
    showDaySchedules(day);
  }
};

/**
 * 显示日期排班列表
 */
const showDaySchedules = (day) => {
  daySchedulesDialog.date = day.date;
  daySchedulesDialog.visible = true;
};

/**
 * 显示生成排班对话框
 */
const showGenerateDialog = () => {
  generateForm.date_range = [
    new Date(),
    new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
  ];
  generateForm.departments = departmentOptions.value.map((dept) => dept.value);
  generateForm.staff_types = [];
  generateForm.schedule_types = [];
  generateDialog.visible = true;
};

/**
 * 显示快速生成对话框
 */
const showSmartGenerateDialog = () => {
  const nextMonth = new Date();
  nextMonth.setMonth(nextMonth.getMonth() + 1);
  smartGenerateForm.month = nextMonth;
  smartGenerateDialog.visible = true;
};

/**
 * 显示调班对话框
 */
const showAdjustDialog = (schedule) => {
  adjustDialog.schedule = schedule;
  adjustForm.target_staff_id = "";
  adjustForm.reason = "";
  adjustForm.notify_original = true;
  loadAvailableStaff(schedule);
  adjustDialog.visible = true;
};

/**
 * 显示请假对话框
 */
const showLeaveDialog = (schedule) => {
  leaveDialog.schedule = schedule;
  leaveForm.leave_type = "";
  leaveForm.start_time = "";
  leaveForm.end_time = "";
  leaveForm.reason = "";
  leaveForm.files = [];
  leaveDialog.visible = true;
};

/**
 * 显示取消排班对话框
 */
const showCancelDialog = async (schedule) => {
  try {
    await ElMessageBox.confirm(
      `确定要取消 ${schedule.staff_name} 在 ${formatDisplayDate(
        schedule.schedule_date
      )} 的排班吗？`,
      "确认取消排班",
      {
        type: "warning",
        confirmButtonText: "确定取消",
        cancelButtonText: "再想想",
      }
    );

    await cancelSchedule(schedule);
  } catch (error) {
    if (error !== "cancel") {
      console.error("取消排班操作失败:", error);
      ElMessage.error("取消排班失败");
    }
  }
};

/**
 * 显示编辑排班对话框
 */
const showEditDialog = (schedule) => {
  ElMessage.info("编辑功能开发中...");
  // TODO: 实现编辑功能
};

// ==================== 业务操作方法 ====================

// 添加处理生成确认的方法
const handleGenerateConfirm = async (generateData) => {
  try {
    const { instances, overwriteStrategy, notes } = generateData;

    // 构建请求参数
    const requestData = {
      instances: instances.map((instance) => ({
        ...instance,
        create_by: store.state.user?.user_id,
      })),
      overwriteStrategy: overwriteStrategy,
      notes: notes,
      created_by: store.state.user?.user_id,
    };

    console.log("请求数据:", requestData);

    // 调用后端接口
    const response = await generateScheduleInstances(requestData);

    if (response && response.code == 200) {
      ElMessage.success(
        `成功生成 ${instances.length} 条排班数据（策略：${overwriteStrategy}）`
      );
      // 重新加载数据
      loadScheduleInstances();
    } else {
      ElMessage.error(response.msg || "排班生成失败");
    }
  } catch (error) {
    console.error("生成排班失败:", error);
    ElMessage.error("生成排班失败");
  }
};

const handleGenerateCancel = () => {
  console.log("用户取消了生成操作");
};

// ============ 处理智能排班的方法 =============
/**
 * 处理智能排班确认
 */
const handleSmartGenerateConfirm = async (smartGenerateData) => {
  try {
    const { instances, overwriteStrategy, notes, template_based, template_names } = smartGenerateData;

    // 构建请求参数，包含模板信息
    const requestData = {
      instances: instances.map((instance) => ({
        ...instance,
        create_by: store.state.user?.user_id,
      })),
      overwriteStrategy: overwriteStrategy,
      notes: notes,
      created_by: store.state.user?.user_id,
      template_based: template_based || false,
      template_names: template_names || []
    };

    console.log("智能排班请求数据:", requestData);

    //暂时不提交，先测试

    // 调用后端接口
    const response = await generateScheduleInstances(requestData);

    if (response && response.code == 200) {
      const templateInfo = template_based ? `（基于模板：${template_names.join(', ')}）` : '';
      ElMessage.success(
        `成功生成 ${instances.length} 条排班数据${templateInfo}`
      );
      // 重新加载数据
      loadScheduleInstances();
    } else {
      ElMessage.error(response.msg || "智能排班生成失败");
    }
  } catch (error) {
    console.error("智能排班失败:", error);
    ElMessage.error("智能排班失败");
  }
};

const handleSmartGenerateCancel = () => {
  console.log("用户取消了智能排班操作");
};

/**
 * 确认调班操作
 */
const confirmAdjust = async () => {
  if (!adjustForm.target_staff_id) {
    ElMessage.warning("请选择接替人员");
    return;
  }

  try {
    adjustLoading.value = true;

    // TODO: 替换为真实API调用
    await new Promise((resolve) => setTimeout(resolve, 1000));

    ElMessage.success("调班操作成功");
    adjustDialog.visible = false;
    loadScheduleInstances();
  } catch (error) {
    console.error("调班操作失败:", error);
    ElMessage.error("调班失败");
  } finally {
    adjustLoading.value = false;
  }
};

/**
 * 确认请假申请
 */
const confirmLeave = async () => {
  if (!leaveFormRef.value) return;

  try {
    // 表单验证
    await leaveFormRef.value.validate();

    leaveLoading.value = true;

    // TODO: 替换为真实API调用
    await new Promise((resolve) => setTimeout(resolve, 1000));

    ElMessage.success("请假申请提交成功");
    leaveDialog.visible = false;
    loadScheduleInstances();
  } catch (error) {
    if (error.errors) {
      ElMessage.warning("请完善表单信息");
    } else {
      console.error("请假申请失败:", error);
      ElMessage.error("请假申请失败");
    }
  } finally {
    leaveLoading.value = false;
  }
};

/**
 * 恢复排班状态
 */
const restoreSchedule = async (schedule) => {
  try {
    // TODO: 替换为真实API调用
    await new Promise((resolve) => setTimeout(resolve, 500));

    ElMessage.success("排班已恢复");
    loadScheduleInstances();
  } catch (error) {
    console.error("恢复排班失败:", error);
    ElMessage.error("恢复排班失败");
  }
};

/**
 * 取消排班
 */
const cancelSchedule = async (schedule) => {
  try {
    // TODO: 替换为真实API调用
    await new Promise((resolve) => setTimeout(resolve, 500));

    ElMessage.success("排班已取消");
    loadScheduleInstances();
  } catch (error) {
    console.error("取消排班失败:", error);
    ElMessage.error("取消排班失败");
  }
};

// ==================== 工具方法 ====================

/**
 * 创建日期数据对象
 */
const createDayData = (date, isCurrentMonth) => {
  return {
    date: formatDate(date),
    day: date.getDate(),
    isCurrentMonth,
    isToday: isToday(date),
    isWeekend: isWeekend(date),
  };
};

/**
 * 获取周的开始日期（周一）
 */
const getStartOfWeek = (date) => {
  const d = new Date(date);
  const day = d.getDay();
  const diff = d.getDate() - day + (day === 0 ? -6 : 1); // 周一开始
  return new Date(d.setDate(diff));
};

/**
 * 获取班次时间范围
 */
const getTimeSlotRange = (slot) => {
  const rangeMap = {
    morning: { startHour: 7, endHour: 15 },
    afternoon: { startHour: 15, endHour: 23 },
    night: { startHour: 23, endHour: 31 }, // 跨天处理
    full_day: { startHour: 8, endHour: 17 },
    office: { startHour: 9, endHour: 18 },
  };
  return rangeMap[slot];
};

/**
 * 加载可用人员列表（用于调班）
 */
const loadAvailableStaff = async (schedule) => {
  // TODO: 替换为真实API调用，根据科室、时间等条件筛选
  availableStaffOptions.value = [
    { value: 2, label: "李医生 - 临床心理科" },
    { value: 6, label: "陈医生 - 健康管理中心" },
    { value: 7, label: "周医生 - 感染科" },
  ];
};

/**
 * 处理请假文件上传
 */
const handleLeaveFileChange = (file, fileList) => {
  leaveForm.files = fileList;
};

/**
 * 禁用过去的月份
 */
const disabledPastMonths = (time) => {
  const now = new Date();
  return (
    time.getTime() < new Date(now.getFullYear(), now.getMonth(), 1).getTime()
  );
};

// ==================== 格式化方法 ====================

/**
 * 格式化日期为 YYYY-MM-DD 修复时区问题
 */
const formatDate = (date) => {
  // 方法1：使用本地时间
  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, "0");
  const day = String(date.getDate()).padStart(2, "0");
  return `${year}-${month}-${day}`;
};

/**
 * 格式化显示日期
 */
const formatDisplayDate = (dateStr) => {
  const date = new Date(dateStr);
  return date.toLocaleDateString("zh-CN", {
    year: "numeric",
    month: "long",
    day: "numeric",
    weekday: "short",
  });
};

/**
 * 格式化班次时间
 */
const formatTimeSlot = (slot) => {
  try {
    // 确保 timeSlotList 已加载且不为空
    if (!timeSlotList.value || timeSlotList.value.length === 0) {
      console.warn("班次时间列表未加载或为空");
      return slot; // 返回原始代码作为fallback
    }

    const timeSlot = timeSlotList.value.find((item) => item.slot_code === slot);

    // 如果找不到对应的班次，返回原始代码
    if (!timeSlot) {
      console.warn(`未找到班次代码: ${slot}`);
      return slot;
    }

    return timeSlot.slot_name || slot;
  } catch (error) {
    console.error("格式化班次时间出错:", error);
    // 出错时返回原始代码
    return slot;
  }
};

/**
 * 格式化时间范围
 */
const formatTimeRange = (slot) => {
  const timeSlot = timeSlotList.value.find((item) => item.slot_code === slot);
  return timeSlot
    ? `${timeSlot.start_time.slice(0, 5)} - ${timeSlot.end_time.slice(0, 5)}`
    : slot;
};

/**
 * 格式化排班类型
 */
const formatScheduleType = (type) => {
  // 使用从API加载的排班类型数据
  const typeConfig = sheduleTypeList.value?.find(
    (item) => item.type_code === type
  );
  if (typeConfig) {
    return typeConfig.type_name;
  }

  // 如果没有找到对应的类型配置，返回原始类型代码
  return type;
};

/**
 * 格式化人员类型
 */
const formatStaffType = (type) => {
  // 使用从 getStaffTypeList API 加载的人员类型数据
  const typeConfig = staffTypeOptions.value?.find(
    (item) => item.value === type
  );
  return typeConfig ? typeConfig.label : type;
};

/**
 * 格式化状态文本
 */
const formatStatus = (status) => {
  const statusMap = {
    0: "取消",
    1: "正常",
    2: "调班",
    3: "请假",
  };
  return statusMap[status] || "未知";
};

/**
 * 格式化金额
 */
const formatAmount = (amount) => {
  return parseFloat(amount || 0).toFixed(2);
};

// ==================== 样式相关方法 ====================

/**
 * 获取排班状态样式类
 */
const getScheduleStatusClass = (schedule) => {
  const statusMap = {
    0: "cancelled",
    1: "normal",
    2: "adjusted",
    3: "leave",
  };
  return statusMap[schedule.status] || "normal";
};

/**
 * 获取状态标签类型
 */
const getStatusTagType = (status) => {
  const typeMap = {
    0: "danger",
    1: "success",
    2: "warning",
    3: "info",
  };
  return typeMap[status] || "info";
};

/**
 * 获取排班类型标签类型
 */
const getScheduleTypeTag = (type) => {
  const tagMap = {
    outpatient: "success",
    inpatient: "primary",
    pharmacy: "warning",
    billing: "danger",
    registration: "info",
    office: "",
    service: "warning",
    emergency: "danger",
    surgery: "success",
  };
  return tagMap[type] || "info";
};

/**
 * 获取班次类型标签
 */
const getShiftType = (slot) => {
  const typeMap = {
    morning: "success",
    afternoon: "warning",
    night: "danger",
    full_day: "primary",
    office: "info",
  };
  return typeMap[slot] || "info";
};

/**
 * 获取人员类型图标
 */
const getStaffTypeIcon = (type) => {
  const iconMap = {
    doctor: "👨‍⚕️",
    nurse: "👩‍⚕️",
    pharmacist: "💊",
    finance: "💰",
    registration: "🏥",
    administrative: "📋",
    logistics: "🔧",
  };
  return iconMap[type] || "👤";
};

/**
 * 获取排班块样式（日视图）
 */
const getScheduleBlockStyle = (schedule) => {
  const range = getTimeSlotRange(schedule.time_slot_code);
  if (!range) return {};

  const top = (range.startHour / 24) * 100;
  const height = ((range.endHour - range.startHour) / 24) * 100;

  return {
    top: `${top}%`,
    height: `${height}%`,
  };
};

/**
 * 获取患者数量标签类型
 */
const getPatientCountType = (schedule) => {
  if (!schedule.max_patients) return "info";
  const ratio = (schedule.actual_patients || 0) / schedule.max_patients;
  if (ratio >= 0.9) return "danger";
  if (ratio >= 0.7) return "warning";
  return "success";
};

// ==================== 工具函数 ====================

/**
 * 判断是否为今天
 */
const isToday = (date) => {
  const today = new Date();
  if (typeof date === "string") {
    return date === formatDate(today);
  }
  return date.toDateString() === today.toDateString();
};

/**
 * 判断是否为过去日期
 */
const isPastDate = (dateStr) => {
  const date = new Date(dateStr);
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  return date < today;
};

/**
 * 判断是否为周末
 */
const isWeekend = (date) => {
  const day = date.getDay();
  return day === 0 || day === 6;
};

/**
 * 判断是否需要业务信息
 */
const requiresBusinessInfo = (scheduleType) => {
  return ["outpatient", "pharmacy", "billing", "registration"].includes(
    scheduleType
  );
};

/**
 * 根据科室ID获取科室名称
 */
const getDepartmentName = (departmentId) => {
  const dept = departmentList.value.find(
    (d) => d.department_id === departmentId
  );
  return dept ? dept.department_name : "未知科室";
};

/**
 * 根据职称ID和人员类型获取职称名称
 */
const getProfessionalTitle = (professionalId, staffType) => {
  // 这里需要根据不同的职称表来获取职称名称
  // 在实际应用中，您可能需要预加载这些职称数据
  const titleMaps = {
    doctor: {
      1: "主任医师",
      2: "副主任医师",
      3: "主治医师",
      4: "住院医师",
    },
    nurse: {
      1: "主任护师",
      2: "副主任护师",
      3: "主管护师",
      4: "护师",
      5: "护士",
    },
    pharmacist: {
      1: "主任药师",
      2: "副主任药师",
      3: "主管药师",
      4: "药师",
      5: "药士",
    },
    finance: {
      1: "实习收费员",
      2: "初级收费员",
      3: "中级收费员",
      4: "高级收费员",
      5: "会计助理",
      6: "初级会计师",
      7: "中级会计师",
      8: "高级会计师",
      9: "出纳员",
      10: "高级出纳",
      11: "财务主管",
      12: "财务经理",
    },
    manager: {
      1: "高级工程师",
      2: "副高级工程师",
      3: "工程师",
      4: "初级工程师",
    },
  };

  const map = titleMaps[staffType];
  return map ? map[professionalId] || "未知职称" : "未知职称";
};

/**
 * 根据人员类型和部门筛选可用人员
 */
const getAvailableStaffByTypeAndDepartment = (
  staffType,
  departmentIds = []
) => {
  const filteredStaff = allStaffList.value.filter((staff) => {
    // 筛选在职人员
    if (staff.status !== 1 && staff.status !== 0) return false; // 1在职，0在职（不同表状态值可能不同）

    // 筛选人员类型
    if (staff.staff_type !== staffType) return false;

    // 筛选部门
    if (
      departmentIds.length > 0 &&
      !departmentIds.includes(staff.department_id)
    ) {
      return false;
    }

    return true;
  });

  return filteredStaff.map((staff) => ({
    value: staff.id,
    label: `${staff.name} - ${staff.department_name} - ${staff.professional_title}`,
    raw: staff,
  }));
};
// ==================== 其他功能方法 ====================

/**
 * 导出排班表
 */
const exportSchedule = () => {
  ElMessage.info("导出功能开发中...");
  // TODO: 实现导出功能
};

/**
 * 刷新数据
 */
const refreshData = () => {
  loadScheduleInstances();
  ElMessage.success("数据已刷新");
};

// ==================== 初始化方法 ====================

/**
 * 加载初始化数据
 */
const loadInitData = async () => {
  // 按顺序加载基础数据
  await load_departments_list(); // 加载科室选项
  await load_staff_types_list(); // 加载人员类型选项
  await load_time_slots_list(); // 加载班次时间选项
  await load_schedule_type_list(); // 加载排班类型数据

  // 加载人员数据
  await loadAllStaffData();
  await loadFeeItems(); // 加载费用项目
  await loadScheduleTemplates(); // 加载排班模板

  //最后加载排班实例数据
  loadScheduleInstances();
};

// ==========加载科室数据列表==========
const load_departments_list = async () => {
  try {
    const response = await getDepartmentList();
    if (response && response.data) {
      departmentOptions.value = response.data.map((dept) => ({
        value: dept.department_id,
        label: dept.department_name,
      }));
      departmentList.value = response.data; //存入数据，避免重复加载
      allDepartmentOptions.value = [...departmentOptions.value]; // 保存完整列表
      filteredDepartmentOptions.value = allDepartmentOptions.value.slice(0, 10); // 初始显示前10条
    }
  } catch (error) {
    console.error("加载科室列表失败:", error);
  }
};

const scheduleTypesList = ref([]);
// ==========加载人员类型数据列表==========
const load_staff_types_list = async () => {
  try {
    const response = await getStaffTypeList();
    if (response && response.data) {
      staffTypeOptions.value = response.data.map((type) => ({
        value: type.type_code,
        label: type.type_name,
      }));
      scheduleTypesList.value = response.data;
    }
  } catch (error) {
    console.error("加载人员类型列表失败:", error);
  }
};
// ==========加载班次时间数据列表==========
const load_time_slots_list = async () => {
  try {
    const response = await getTimeSlotList();
    if (response && response.code == 200) {
      timeSlotOptions.value = response.data.map((type) => ({
        value: type.slot_code,
        label: type.slot_name,
      }));
      timeSlotList.value = response.data; //预加载
    }
  } catch (error) {
    console.error("加载班次时间选项列表失败:", error);
  }
};

// ==========加载排班类型数据列表==========
const load_schedule_type_list = async () => {
  try {
    const res = await getScheduleTypeList();
    if (res && res.code == 200) {
      sheduleTypeList.value = res.data;
    }
  } catch (error) {
    console.error("加载排班类型数据列表失败:", error);
  }
};

// ==================== 人员数据加载方法 ====================

/**
 * 加载医生列表
 */
const loadDoctorsList = async () => {
  try {
    const response = await getDoctorList();
    if (response && response.data) {
      staffData.doctors = response.data.map((doctor) => ({
        id: doctor.doctor_id,
        name: doctor.doctor_name,
        work_id: doctor.work_id,
        department_id: doctor.department_id,
        department_name: getDepartmentName(doctor.department_id),
        professional_title: getProfessionalTitle(
          doctor.professional_id,
          "doctor"
        ),
        phone: doctor.phone,
        status: doctor.status,
        avatar: doctor.doctor_avatar,
      }));
    }
  } catch (error) {
    console.error("加载医生列表失败:", error);
  }
};

/**
 * 加载护士列表
 */
const loadNursesList = async () => {
  try {
    const response = await getNurseList();
    if (response && response.data) {
      staffData.nurses = response.data.map((nurse) => ({
        id: nurse.nurse_id,
        name: nurse.nurse_name,
        work_id: nurse.work_id,
        department_id: nurse.department_id,
        department_name: getDepartmentName(nurse.department_id),
        professional_title: getProfessionalTitle(
          nurse.professional_id,
          "nurse"
        ),
        phone: nurse.phone,
        status: nurse.status,
        work_years: nurse.work_years,
        avatar: nurse.nurse_avatar,
      }));
    }
  } catch (error) {
    console.error("加载护士列表失败:", error);
  }
};

/**
 * 加载药剂师列表
 */
const loadPharmacistsList = async () => {
  try {
    const response = await getPharmacistList();
    if (response && response.data) {
      staffData.pharmacists = response.data.map((pharmacist) => ({
        id: pharmacist.pharmacist_id,
        name: pharmacist.pharmacist_name,
        work_id: pharmacist.work_id,
        department_id: pharmacist.department_id,
        department_name: getDepartmentName(pharmacist.department_id),
        professional_title: getProfessionalTitle(
          pharmacist.professional_id,
          "pharmacist"
        ),
        phone: pharmacist.phone,
        status: pharmacist.status,
        license_number: pharmacist.license_number,
        avatar: pharmacist.pharmacist_avatar,
      }));
    }
  } catch (error) {
    console.error("加载药剂师列表失败:", error);
  }
};

/**
 * 加载财务人员列表
 */
const loadFinanceStaffList = async () => {
  try {
    const response = await getFinanceStaffList();
    if (response && response.data) {
      staffData.financeStaff = response.data.map((finance) => ({
        id: finance.finance_id,
        name: finance.finance_name,
        work_id: finance.work_id,
        department_id: finance.department_id,
        department_name: getDepartmentName(finance.department_id),
        professional_title: getProfessionalTitle(
          finance.professional_id,
          "finance"
        ),
        staff_type: finance.staff_type,
        phone: finance.phone,
        status: finance.status,
        window_number: finance.window_number,
        service_type: finance.service_type,
        avatar: finance.finance_avatar,
      }));
    }
  } catch (error) {
    console.error("加载财务人员列表失败:", error);
  }
};

/**
 * 加载管理员列表
 */
const loadManagersList = async () => {
  try {
    const response = await getManagerList();
    if (response && response.data) {
      staffData.managers = response.data.map((manager) => ({
        id: manager.manager_id,
        name: manager.manager_name,
        work_id: manager.work_id,
        department_id: manager.department_id,
        department_name: getDepartmentName(manager.department_id),
        professional_title: getProfessionalTitle(
          manager.professional_id,
          "manager"
        ),
        phone: manager.phone,
        status: manager.status,
        avatar: null, // 管理员表没有头像字段
      }));
    }
  } catch (error) {
    console.error("加载管理员列表失败:", error);
  }
};

/**
 * 加载所有人员数据
 */
const loadAllStaffData = async () => {
  try {
    await Promise.all([
      loadDoctorsList(),
      loadNursesList(),
      loadPharmacistsList(),
      loadFinanceStaffList(),
      // loadManagersList()
    ]);
    //console.log("所有人员数据加载完成:", allStaffList.value);
  } catch (error) {
    console.error("加载人员数据失败:", error);
  }
};

/**
 * 加载费用项目列表
 */
const loadFeeItems = async () => {
  try {
    // 这里需要您提供获取费用项目列表的API
    const response = await getFeeItemList();
    feeItemsList.value = response.data;
    //console.log("费用项目数据加载完成:", feeItemsList.value);
    return response.data || [];
  } catch (error) {
    console.error("加载费用项目失败:", error);
    return [];
  }
};

/**
 * 加载排班模板数据
 */
const loadScheduleTemplates = async () => {
  try {
    //这里需要您提供获取排班模板的API
    const response = await getScheduleTemplateList();
    scheduleTemplates.value = response.data || [];
    //console.log("排班模板数据加载完成:", scheduleTemplates.value);
    // scheduleTemplates.value = [];
    // console.log("排班模板数据加载完成:", scheduleTemplates.value.length);
  } catch (error) {
    console.error("加载排班模板失败:", error);
  }
};

/**
 * 组件挂载时初始化
 */
onMounted(() => {
  loadInitData();
});

// 监听人员类型变化，动态更新可用人员
watch(
  () => generateForm.staff_types,
  (newTypes) => {
    if (newTypes.length > 0) {
      // 当人员类型变化时，可以在这里更新相关数据
      console.log("选中的人员类型:", newTypes);
    }
  }
);
</script>

<style scoped lang="scss">
/* ==================== SCSS变量定义 ==================== */
$primary-color: #1890ff;
$success-color: #52c41a;
$warning-color: #fa8c16;
$danger-color: #f5222d;
$info-color: #909399;

$bg-color: #f5f7fa;
$bg-white: #ffffff;
$bg-light: #fafafa;
$bg-lighter: #f8f9fa;

$text-primary: #303133;
$text-regular: #606266;
$text-secondary: #909399;
$text-placeholder: #c0c4cc;

$border-color: #ebeef5;
$border-light: #f0f0f0;

$shadow-light: 0 2px 4px rgba(0, 0, 0, 0.1);
$shadow-medium: 0 2px 8px rgba(0, 0, 0, 0.1);
$shadow-heavy: 0 4px 12px rgba(0, 0, 0, 0.15);

$border-radius: 8px;
$border-radius-sm: 4px;
$border-radius-lg: 12px;

$transition: all 0.3s ease;
$transition-fast: all 0.2s ease;

/* ==================== 混入(Mixins) ==================== */
@mixin flex-center {
  display: flex;
  align-items: center;
  justify-content: center;
}

@mixin flex-between {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

@mixin flex-column {
  display: flex;
  flex-direction: column;
}

@mixin text-ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

@mixin scrollbar-style {
  &::-webkit-scrollbar {
    width: 4px;
  }

  &::-webkit-scrollbar-track {
    background: #f1f1f1;
    border-radius: 2px;
  }

  &::-webkit-scrollbar-thumb {
    background: #c1c1c1;
    border-radius: 2px;
  }

  &::-webkit-scrollbar-thumb:hover {
    background: #a8a8a8;
  }
}

@mixin card-style {
  background: $bg-white;
  border-radius: $border-radius;
  box-shadow: $shadow-light;
  overflow: hidden;
}

@mixin status-badge($color) {
  background: $color;
  color: $bg-white;
  font-size: 12px;
  padding: 2px 6px;
  border-radius: $border-radius-sm;
  font-weight: 500;
}

@mixin gradient-bg($start-color, $end-color) {
  background: linear-gradient(135deg, $start-color 0%, $end-color 100%);
}

/* ==================== 全局样式 ==================== */
.content-area {
  flex: 1;
  padding: 24px;
  background-color: #f5f7fa;
  height: 0;  // 添加这行
  min-height: 100%;  // 添加这行
  overflow-y: auto;  // 确保有这行

  @media (max-width: 768px) {
    padding: 10px;
  }
}

/* ==================== 日历头部样式 ==================== */
.calendar-header {
  @include card-style;
  padding: 20px;
  margin-bottom: 20px;

  @media (max-width: 768px) {
    padding: 16px;
  }
}

.calendar-controls {
  @include flex-between;
  flex-wrap: wrap;
  gap: 16px;

  @media (max-width: 1200px) {
    flex-direction: column;
    align-items: flex-start;

    .date-navigation {
      order: 1;
    }

    .calendar-actions {
      order: 2;
      width: 100%;
      justify-content: flex-end;
    }
  }
}

.date-navigation {
  @include flex-center;
  gap: 12px;
}

.current-period {
  font-size: 16px;
  font-weight: 600;
  min-width: 200px;
  text-align: center;
  color: $text-primary;

  @media (max-width: 768px) {
    min-width: 150px;
    font-size: 14px;
  }
}

.calendar-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;

  @media (max-width: 1200px) {
    justify-content: flex-end;
  }

  @media (max-width: 480px) {
    flex-direction: column;
    width: 100%;

    .el-button {
      width: 100%;
      justify-content: center;
    }
  }
}

/* ==================== 筛选卡片样式 ==================== */
.filter-card {
  @include card-style;
  padding: 20px;
  margin-bottom: 20px;

  @media (max-width: 768px) {
    padding: 16px;
  }
}

.filter-row {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-bottom: 16px;

  @media (max-width: 1200px) {
    flex-direction: column;
  }
}

.filter-item {
  @include flex-column;
  min-width: 200px;
  flex: 1;

  @media (max-width: 1200px) {
    min-width: 100%;
  }
}

.filter-label {
  font-size: 14px;
  color: $text-regular;
  margin-bottom: 8px;
  font-weight: 500;
}

.filter-actions {
  @include flex-between;
  gap: 10px;
  padding-top: 16px;
  border-top: 1px solid $border-color;
}

/* ==================== 月视图样式 ==================== */
.month-view {
  @include card-style;
}

.month-grid {
  @include flex-column;
}

.month-header {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  background: $bg-color;
  border-bottom: 1px solid $border-color;
}

.weekday-header {
  padding: 16px;
  text-align: center;
  font-weight: 600;
  color: $text-regular;
  border-right: 1px solid $border-color;
  font-size: 14px;

  &:last-child {
    border-right: none;
  }
}

.month-body {
  @include flex-column;
}

.week-row {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  border-bottom: 1px solid $border-color;
  min-height: 140px;

  &:last-child {
    border-bottom: none;
  }
}

.day-cell {
  padding: 8px;
  border-right: 1px solid $border-color;
  background: $bg-white;
  cursor: pointer;
  transition: $transition;
  position: relative;
  min-height: 140px;

  &:last-child {
    border-right: none;
  }

  &.current-month {
    background: $bg-white;
  }

  &:not(.current-month) {
    background: $bg-light;
    color: $text-placeholder;
  }

  &.today {
    background: #f0f9ff;
    border: 2px solid $primary-color;
  }

  &.weekend {
    background: #fef6f6;

    &:not(.current-month) {
      background: #faf0f0;
    }
  }

  &.has-schedules {
    &:hover {
      background: $bg-color;
      transform: translateY(-2px);
      box-shadow: $shadow-medium;
    }
  }

  @media (max-width: 480px) {
    min-height: 120px;
    padding: 6px;
  }
}

.day-header {
  @include flex-between;
  margin-bottom: 8px;
  padding-bottom: 4px;
  border-bottom: 1px solid $border-light;
}

.day-number {
  font-weight: 500;
  font-size: 14px;
  color: $text-primary;

  .day-cell:not(.current-month) & {
    color: $text-placeholder;
  }
}

.today-badge {
  @include status-badge($primary-color);
}

.schedule-count {
  @include status-badge($danger-color);
}

.schedule-items {
  max-height: 100px;
  overflow-y: auto;
  padding-right: 2px;
  @include scrollbar-style;
}

.schedule-item {
  font-size: 12px;
  padding: 6px 8px;
  margin-bottom: 4px;
  border-radius: $border-radius-sm;
  cursor: pointer;
  border-left: 3px solid;
  transition: $transition-fast;
  background: $bg-white;
  box-shadow: $shadow-light;

  &:hover {
    transform: translateX(2px);
    box-shadow: $shadow-heavy;
  }

  &.normal {
    border-left-color: $primary-color;
    @include gradient-bg(#f0f9ff, #e6f7ff);
  }

  &.cancelled {
    border-left-color: $danger-color;
    @include gradient-bg(#fef0f0, #fde2e2);
    text-decoration: line-through;
    opacity: 0.7;
  }

  &.adjusted {
    border-left-color: $warning-color;
    @include gradient-bg(#fdf6ec, #faecd8);
  }

  &.leave {
    border-left-color: $info-color;
    @include gradient-bg(#f4f4f5, #e9e9eb);
  }

  @media (max-width: 768px) {
    font-size: 10px;
    padding: 4px 6px;
  }
}

.schedule-time {
  font-weight: 600;
  color: $text-primary;
  margin-bottom: 2px;
  font-size: 11px;
}

.schedule-staff {
  color: $text-regular;
  font-size: 11px;
  line-height: 1.3;
}

.schedule-more {
  font-size: 11px;
  color: $primary-color;
  text-align: center;
  padding: 4px;
  cursor: pointer;
  border-radius: 2px;
  background: #f0f9ff;
  margin-top: 2px;
  transition: $transition-fast;

  &:hover {
    background: $primary-color;
    color: $bg-white;
  }
}

/* ==================== 周视图样式 ==================== */
.week-view {
  @include card-style;
}

.week-grid {
  display: flex;
  min-height: 600px;

  @media (max-width: 768px) {
    flex-direction: column;
    min-height: auto;
  }
}

.time-column {
  width: 100px;
  flex-shrink: 0;
  border-right: 1px solid $border-color;

  @media (max-width: 768px) {
    width: 100%;
    display: flex;
  }
}

.time-header {
  height: 80px;
  border-bottom: 1px solid $border-color;
  @include flex-center;
  font-weight: 600;
  background: $bg-color;
  color: $text-primary;
  font-size: 14px;
}

.time-slot {
  height: 100px;
  border-bottom: 1px solid $border-color;
  @include flex-center;
  font-size: 13px;
  color: $text-regular;
  font-weight: 500;
  background: $bg-light;

  @media (max-width: 768px) {
    flex: 1;
    height: 60px;
  }
}

.day-column {
  flex: 1;
  border-right: 1px solid $border-color;
  @include flex-column;

  &:last-child {
    border-right: none;
  }

  &.weekend {
    background: #fef6f6;
  }

  &.today {
    background: #f0f9ff;
  }

  @media (max-width: 768px) {
    min-width: 200px;
  }
}

.week-view {
  .day-header {
    height: 80px;
    border-bottom: 1px solid $border-color;
    @include flex-center;
    background: $bg-color;
    padding: 0 16px;

    @media (max-width: 768px) {
      height: 60px;
    }
  }
}

.date-info {
  text-align: center;
}

.weekday {
  font-weight: 600;
  color: $text-primary;
  font-size: 14px;
  margin-bottom: 4px;
}

.date {
  font-size: 12px;
  color: $text-secondary;

  .day-column.today & {
    color: $primary-color;
    font-weight: 500;
  }
}

.day-schedules {
  @include flex-column;
  flex: 1;
}

.schedule-cell {
  height: 100px;
  border-bottom: 1px solid $border-color;
  padding: 4px;
  position: relative;
  transition: $transition-fast;

  &.has-schedule {
    background: $bg-light;
  }

  &:hover {
    background: #f0f9ff;
  }

  &:last-child {
    border-bottom: none;
  }

  @media (max-width: 768px) {
    height: 60px;
  }
}

.week-view {
  .schedule-item {
    height: 100%;
    @include flex-column;
    justify-content: center;
    padding: 8px;
    margin: 0;
  }

  .staff-name {
    font-weight: 600;
    font-size: 12px;
    color: $text-primary;
    margin-bottom: 4px;
  }

  .schedule-type {
    font-size: 11px;
    color: $text-regular;
    margin-bottom: 2px;
  }

  .schedule-location {
    font-size: 10px;
    color: $text-secondary;
  }
}

/* ==================== 日视图样式 ==================== */
.day-view {
  @include card-style;
}

.day-header {
  padding: 24px;
  border-bottom: 1px solid $border-color;
  background: $bg-color;
  @include flex-between;
  align-items: center;

  h3 {
    margin: 0;
    color: $text-primary;
    font-size: 20px;
    font-weight: 600;

    @media (max-width: 768px) {
      font-size: 18px;
    }
  }
}

.day-stats {
  display: flex;
  gap: 24px;

  @media (max-width: 1200px) {
    flex-wrap: wrap;
    gap: 12px;
  }
}

.stat-item {
  font-size: 14px;
  color: $text-regular;
  padding: 8px 16px;
  background: $bg-white;
  border-radius: 6px;
  box-shadow: $shadow-light;

  @media (max-width: 1200px) {
    flex: 1;
    min-width: 120px;
    text-align: center;
  }

  .success {
    color: $success-color;
    font-weight: 600;
  }

  .warning {
    color: $warning-color;
    font-weight: 600;
  }

  .danger {
    color: $danger-color;
    font-weight: 600;
  }
}

.day-timeline {
  max-height: 600px;
  overflow-y: auto;
}

.hour-row {
  display: flex;
  border-bottom: 1px solid $border-color;
  min-height: 80px;

  &:last-child {
    border-bottom: none;
  }

  @media (max-width: 768px) {
    min-height: 60px;
  }
}

.hour-label {
  width: 80px;
  flex-shrink: 0;
  @include flex-center;
  align-items: flex-start;
  padding: 12px;
  background: $bg-light;
  border-right: 1px solid $border-color;
  font-size: 13px;
  color: $text-regular;
  font-weight: 500;

  @media (max-width: 768px) {
    width: 60px;
    padding: 8px;
  }
}

.hour-schedules {
  flex: 1;
  position: relative;
  padding: 8px;
  background: $bg-white;
}

.schedule-block {
  position: absolute;
  left: 8px;
  right: 8px;
  background: $bg-white;
  border-radius: 6px;
  box-shadow: $shadow-medium;
  cursor: pointer;
  transition: $transition;
  border-left: 4px solid;
  overflow: hidden;

  &:hover {
    transform: translateY(-2px);
    box-shadow: $shadow-heavy;
  }

  &.normal {
    border-left-color: $primary-color;
    @include gradient-bg(#f0f9ff, #e6f7ff);
  }

  &.cancelled {
    border-left-color: $danger-color;
    @include gradient-bg(#fef0f0, #fde2e2);
  }

  &.adjusted {
    border-left-color: $warning-color;
    @include gradient-bg(#fdf6ec, #faecd8);
  }

  &.leave {
    border-left-color: $info-color;
    @include gradient-bg(#f4f4f5, #e9e9eb);
  }
}

.schedule-content {
  padding: 12px;
  height: 100%;
  @include flex-column;
  justify-content: center;
}

.schedule-time {
  font-weight: 600;
  font-size: 12px;
  color: $text-primary;
  margin-bottom: 4px;
}

.schedule-staff {
  font-size: 14px;
  font-weight: 500;
  color: $primary-color;
  margin-bottom: 2px;
}

.schedule-type {
  font-size: 12px;
  color: $text-regular;
  margin-bottom: 2px;
}

.schedule-location {
  font-size: 11px;
  color: $text-secondary;
}

/* ==================== 对话框样式 ==================== */
.schedule-detail {
  max-height: 70vh;
  overflow-y: auto;
  padding-right: 8px;
  @include scrollbar-style;
}

.staff-info {
  display: flex;
  align-items: center;
  gap: 12px;

  @media (max-width: 768px) {
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
  }
}

.staff-details {
  flex: 1;
}

.staff-name {
  font-weight: 600;
  font-size: 16px;
  color: $text-primary;
  margin-bottom: 4px;
}

.staff-meta {
  font-size: 14px;
  color: $text-regular;
  display: flex;
  align-items: center;
  gap: 8px;

  @media (max-width: 768px) {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
  }
}

.avatar-text {
  font-size: 16px;
}

.time-range {
  color: $text-secondary;
  font-size: 12px;
}

.business-info-section {
  margin-top: 20px;
  padding: 16px;
  background: $bg-lighter;
  border-radius: 6px;
}

.business-info-section {
  h4 {
    margin: 0 0 12px 0;
    color: $text-primary;
    font-size: 16px;
    font-weight: 600;
  }
}

.fee-amount {
  color: $danger-color;
  font-weight: 500;
  margin-left: 8px;
}

.patient-ratio {
  color: $text-secondary;
  font-size: 12px;
  margin-left: 4px;
}

.notes-section {
  margin-top: 20px;
  padding: 16px;
  background: #fffbe6;
  border-radius: 6px;
  border-left: 4px solid #faad14;
}

.notes-section {
  h4 {
    margin: 0 0 8px 0;
    color: $text-primary;
    font-size: 16px;
    font-weight: 600;
  }
}

.notes-content {
  color: $text-regular;
  line-height: 1.6;
  font-size: 14px;
}

/* 调班对话框样式 */
.adjust-dialog {
  max-height: 60vh;
  overflow-y: auto;
}

/* 日排班列表样式 */
.day-schedules-list {
  max-height: 70vh;
  overflow-y: auto;
}

.staff-info-cell {
  display: flex;
  align-items: center;
  gap: 12px;

  .staff-details {
    flex: 1;
  }

  .staff-name {
    font-weight: 600;
    font-size: 14px;
    color: $text-primary;
    margin-bottom: 2px;
  }

  .staff-meta {
    font-size: 12px;
    color: $text-secondary;
  }
}

.day-summary {
  background: $bg-lighter !important;
  border-radius: $border-radius;
  margin-top: 20px;
  padding: 16px;

  h4 {
    margin: 0 0 16px 0;
    color: $text-primary;
    font-size: 16px;
    font-weight: 600;
  }
}

.summary-item {
  text-align: center;
  padding: 12px;
  background: $bg-white;
  border-radius: 6px;
  box-shadow: $shadow-light;
}

.summary-label {
  font-size: 12px;
  color: $text-secondary;
  margin-bottom: 4px;
}

.summary-value {
  font-size: 20px;
  font-weight: 600;
  color: $text-primary;

  &.success {
    color: $success-color;
  }

  &.warning {
    color: $warning-color;
  }

  &.danger {
    color: $danger-color;
  }
}

/* ==================== 加载状态样式 ==================== */
.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.8);
  @include flex-center;
  z-index: 1000;
  border-radius: $border-radius;
}

/* ==================== 动画效果 ==================== */
@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.schedule-item,
.schedule-block,
.day-cell {
  animation: fadeIn 0.3s ease-out;
}

/* ==================== 无障碍支持 ==================== */
@media (prefers-reduced-motion: reduce) {
  .schedule-item,
  .schedule-block,
  .day-cell {
    animation: none;
    transition: none;
  }
}

/* 高对比度模式 */
@media (prefers-contrast: high) {
  .schedule-item {
    border-width: 2px;
  }

  .day-cell.today {
    border-width: 3px;
  }

  .schedule-count,
  .today-badge {
    font-weight: 700;
  }
}

/* ==================== 焦点样式 ==================== */
.el-button:focus,
.schedule-item:focus,
.schedule-block:focus,
.day-cell:focus {
  outline: 2px solid $primary-color;
  outline-offset: 2px;
}

/* ==================== 深色模式支持 ==================== */
@media (prefers-color-scheme: dark) {
  $dark-bg: #1a1a1a;
  $dark-card: #2d2d2d;
  $dark-header: #3d3d3d;
  $dark-text: #e0e0e0;
  $dark-border: #404040;

  .content-area {
    background-color: $dark-bg;
  }

  .calendar-header,
  .filter-card,
  .month-view,
  .week-view,
  .day-view {
    background: $dark-card;
    color: $dark-text;
  }

  .month-header,
  .time-header,
  .day-header {
    background: $dark-header;
    color: $dark-text;
  }

  .day-cell {
    background: $dark-card;
    border-color: $dark-border;

    &:not(.current-month) {
      background: #252525;
      color: #666;
    }

    &.today {
      background: #1a3a5f;
    }

    &.weekend {
      background: #3d2d2d;
    }
  }

  .schedule-item {
    background: $dark-header;
    color: $dark-text;

    &.normal {
      background: #1a3a5f;
    }

    &.cancelled {
      background: #5c2d2d;
    }

    &.adjusted {
      background: #5c4a2d;
    }

    &.leave {
      background: #4d4d4d;
    }
  }

  /* 深色模式下的深度选择器 */
  :deep(.el-descriptions__label) {
    color: #b0b0b0;
  }

  :deep(.el-descriptions__content) {
    color: $dark-text;
  }

  :deep(.el-table__header) {
    background-color: $dark-header;
  }

  :deep(.el-table th) {
    background-color: $dark-header;
    color: $dark-text;
  }

  :deep(.el-divider__text) {
    background-color: $dark-card;
    color: $dark-text;
  }
}

/* ==================== 打印样式 ==================== */
@media print {
  .content-area {
    background: $bg-white;
    padding: 0;
  }

  .calendar-header,
  .filter-card,
  .calendar-actions,
  .action-buttons {
    display: none;
  }

  .month-view,
  .week-view,
  .day-view {
    box-shadow: none;
    border: 1px solid #ddd;
  }

  .schedule-item {
    break-inside: avoid;
  }
}

/* ==================== 自定义滚动条 ==================== */
::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 4px;
}

::-webkit-scrollbar-thumb {
  background: #c1c1c1;
  border-radius: 4px;
}

::-webkit-scrollbar-thumb:hover {
  background: #a8a8a8;
}

/* ==================== 选择器深度样式 ==================== */
:deep(.el-descriptions__label) {
  font-weight: 600;
  color: $text-regular;
}

:deep(.el-descriptions__content) {
  color: $text-primary;
}

:deep(.el-tag) {
  border: none;
  font-weight: 500;
}

:deep(.el-table) {
  border-radius: $border-radius;
}

:deep(.el-table__header) {
  background-color: $bg-color;
}

:deep(.el-table th) {
  background-color: $bg-color;
  color: $text-regular;
  font-weight: 600;
}

:deep(.el-table td) {
  padding: 12px 0;
}

:deep(.el-dialog__body) {
  padding: 20px;
}

:deep(.el-divider__text) {
  background-color: $bg-white;
  font-size: 14px;
  color: $text-regular;
}

:deep(.el-form-item__label) {
  font-weight: 500;
}

:deep(.el-select) {
  width: 100%;
}

:deep(.el-date-editor) {
  width: 100%;
}

/* 新增：表单错误提示样式 */
:deep(.el-form-item__error) {
  font-size: 12px;
  margin-top: 4px;
}
</style>